<template>
  <ElDialog
    title="批量操作"
    :visible.sync="visible"
    width="1000px"
    top="0"
    custom-class="fa-options-edit"
    append-to-body
    modal-append-to-body
    :close-on-click-modal="false"
    @closed="$emit('close')"
    @click.native.stop
  >
    <div class="fa-options-edit__tips">
      选项之间用回车键分隔；单个选项字数不超过{{ optionCfg.maxLength }}；选项个数不超过{{ optionCfg.max }}。
    </div>

    <ElForm ref="form" :model="{ value }">
      <ElFormItem prop="value" :rules="rules">
        <ElInput
          class="fa-options-edit__textarea"
          v-model="value"
          type="textarea"
          :rows="16"
          placeholder="请输入选项值..."
          @blur="fix"
        />
      </ElFormItem>
    </ElForm>

    <template #footer>
      <ElButton size="small" @click="visible = false">取消</ElButton>

      <ElButton type="primary" :disabled="disabled" size="small" @click="submit">确定 ({{ result.length }})</ElButton>
    </template>
  </ElDialog>
</template>

<script lang="ts">
import { defineComponent, ref, computed, PropType, onMounted, nextTick } from 'vue'
import config from '@/config'
import { Widget } from '@/models'
import { WidgetType } from '@/types'
import { ElForm } from '@/types/thirdParty'

export default defineComponent({
  name: 'FaOptionsEdit',

  props: {
    /** 控件数据 */
    data: {
      type: Widget,
      required: true
    },

    /** 选项列表 */
    options: {
      type: Array as PropType<string[]>,
      default: () => []
    }
  },

  emits: {
    /** 关闭 */
    close: () => void 0,

    /** 成功 */
    success: (options: string[]) => void 0
  },

  setup(props, { emit }) {
    /** 是否可见 */
    const visible = ref(true)

    /** 选项值 */
    const value = ref('')

    /** 结果 */
    const result = computed(() => {
      const v = value.value.trim()
      return v ? v.split(/\s*\n+\s*/g) : []
    })

    /** 表单 */
    const form = ref<ElForm | null>(null)

    /** 配置 */
    const optionCfg = computed(() => (props.data.type === WidgetType.SELECT ? config.selectOption : config.checkOption))

    onMounted(async () => {
      value.value = props.options.join('\n')

      await nextTick()

      const input = document.querySelector('.fa-options-edit__textarea textarea') as HTMLTextAreaElement | null

      // 默认聚焦
      input?.focus()
    })

    return {
      /** 是否可见 */
      visible,

      /** 选项值 */
      value,

      /** 结果 */
      result,

      /** 表单 */
      form,

      /** 配置 */
      optionCfg,

      /** 表单校验 */
      rules: [
        {
          validator(rule: object, value: string, callback: (error?: Error) => void) {
            const res = result.value
            const len = res.length
            const { max, maxLength } = optionCfg.value

            if (!len) {
              callback(new Error('至少保留一个选项'))
            } else if (len > max) {
              callback(new Error(`选项个数不超过${max}`))
            } else if (res.some(r => r.length >= maxLength)) {
              callback(new Error(`单个选项字数不超过${maxLength}`))
            }

            callback()
          },
          trigger: 'blur'
        }
      ],

      /** 是否禁止提交 */
      disabled: computed(() => {
        const res = result.value
        const len = res.length
        const { max, maxLength } = optionCfg.value

        return !len || len > max || res.some(r => r.length >= maxLength)
      }),

      /** 修整数据，去除空选项和前后空格 */
      fix() {
        const v = value.value
        value.value = v.trim().replace(/\s*(\n)\s*/g, '$1')
      },

      /** 提交 */
      async submit() {
        await form.value?.validate()

        emit('success', result.value)

        visible.value = false
      }
    }
  }
})
</script>

<style lang="scss">
.fa-options-edit {
  top: 33% !important;
  transform: translate(0, -33%);

  &__tips {
    margin-bottom: 8px;
    color: $color-text-primary;
    font-size: 14px;
    line-height: 1.5;
  }

  &__textarea {
    .el-textarea__inner {
      padding: 4px 8px;
      font-size: 14px;
      font-family: inherit;
      line-height: 2;
      resize: none;
    }
  }

  .el-form-item {
    margin-bottom: 18px;

    .el-form-item__error {
      padding-top: 8px;
    }
  }

  .el-dialog {
    &__body {
      padding: 12px 24px;
    }

    &__footer {
      padding: 12px 24px;
      border-top: $border-solid;
    }
  }
}
</style>
